package com.sunop.pantiproblem.controller;

import cn.hutool.json.JSONUtil;
import com.sunop.panticommon.entity.PageResult;
import com.sunop.panticommon.entity.Result;
import com.sunop.pantiproblem.mapper.ProblemMapper;
import com.sunop.pantiproblem.model.*;
import com.sunop.pantiproblem.service.ProblemService;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

/**
 * @since 2025-03-18
 */
@RestController
@RequestMapping("/problem")
@AllArgsConstructor
public class ProblemController {

    private final ProblemService problemService;
    private final ProblemMapper problemMapper;

    @PostMapping("/uploadData")
    public Result uploadData(@RequestBody ProblemInOutputData problemInOutputData) {
        if (!JSONUtil.isTypeJSON(problemInOutputData.getInput()) || !JSONUtil.isTypeJSON(problemInOutputData.getOutput())) {
            return Result.error("测评数据上传失败,input或output为无效json字符串");
        }
        try {
            problemMapper.saveInOut(problemInOutputData);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 设置输入输出到docker
        try {
            problemService.setInput(problemInOutputData.getPid(), "java");
            problemService.setInput(problemInOutputData.getPid(), "cpp");
            problemService.setInput(problemInOutputData.getPid(), "python");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return Result.success(null, "测评数据上传成功");
    }

    // 上传题目
    @PostMapping("/upload")
    @Transactional(rollbackFor = Exception.class)
    public Result upload(@RequestBody Problem problem) {
        if (!JSONUtil.isTypeJSON(problem.getExampleCin()) || !JSONUtil.isTypeJSON(problem.getExampleOut())) {
            return Result.error("测评数据上传失败,input或output为无效json字符串");
        }
        // 先保存到数据库，获取自增 ID
        try {
            problem.setPassNum(0);
            problem.setSubmitNum(0);
            problem.setCommentNum(0);
            problemService.save(problem);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 保存到 ES,异步的不用管，mq会处理
        problemService.saveToES(problem.getId(), problem.getTitle(), problem.getContent());

        return Result.success(null, "题目上传成功");
    }

    // 主页获取题库
    @GetMapping("/list")
    public Result<PageResult> list(@RequestParam(required = true, defaultValue = "10") int pageSize,
                                   @RequestParam(required = true, defaultValue = "10") int pageNum,
                                   @RequestParam(required = false) String sortBy,
                                   @RequestParam(required = false) String orderBy,
                                   @RequestParam(required = false) String difficulty,
                                   @RequestParam(required = false) String tag) {
        try {
            ProblemPageQueryDTO problemPageQueryDTO = new ProblemPageQueryDTO(pageNum, pageSize, difficulty, tag, sortBy, orderBy);
            PageResult pageResult = problemService.pageQuery(problemPageQueryDTO);
            return Result.success(pageResult);
        } catch (Exception e) {
            return Result.error("分页查询题库失败:"+e);
        }
    }

    @GetMapping("/getInfo/{id}")
    public Result<Problem> getProblemInfo(@PathVariable Integer id) {
        try {
            Problem problem = problemService.getById(id);
            return Result.success(problem);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @GetMapping("/listByTitle")
    public Result listByTitle(@RequestBody ProblemPageQueryByTitleDTO problemPageQueryByTitleDTO) {
        if(problemPageQueryByTitleDTO.getTitle().isEmpty() || problemPageQueryByTitleDTO.getPageNum()<1)return Result.error("参数错误");
        List<Integer> pidByTitle = problemService.getPidByTitle(problemPageQueryByTitleDTO.getTitle());
        if (pidByTitle.isEmpty()) {
            return Result.error("未找到题目");
        }
        List<ProblemVO> problems = problemService.pageQueryByTitle(pidByTitle,problemPageQueryByTitleDTO.getPageNum(), problemPageQueryByTitleDTO.getPageSize());
        if(problems.isEmpty())return Result.error("查询题目异常");
        return Result.success(problems);
    }

    @PostMapping("/{problemId}/like")
    public Result like(@PathVariable Integer problemId) {
        return problemService.problemLike(problemId);
    }

    @PostMapping("/{problemId}/unlike")
    public Result unlike(@PathVariable Integer problemId) {
        return problemService.problemUnlike(problemId);
    }

    // 收藏题目
    @PostMapping("/{problemId}/collect")
    public Result collect(@PathVariable Integer problemId) {
        return problemService.collectProblem(problemId);
    }

    // 取消收藏
    @DeleteMapping("/{problemId}/collect")
    public Result uncollect(@PathVariable Integer problemId) {
        return problemService.uncollectProblem(problemId);
    }

    // 查看收藏列表（分页 + 排序）
    @GetMapping("/collect")
    public Result getCollectedProblems(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "false") boolean reverseOrder) {
        return problemService.getCollectedProblems(page, size, reverseOrder);
    }

    // 获取收藏总数
    @GetMapping("/collect/count")
    public Result getCollectedCount() {
        long count = problemService.getCollectedCount();
        return Result.success(count, "获取收藏总数成功");
    }

    // 检查是否已收藏
    @GetMapping("/{problemId}/collect/status")
    public Result isCollected(@PathVariable Integer problemId) {
        boolean isCollected = problemService.isProblemCollected(problemId);
        return Result.success(isCollected, "检查收藏状态成功");
    }
    //fegin
    @GetMapping("/fegin/selectTimeById")
    public Map<String, BigInteger> selectTimeById(@RequestParam("pid") int pid) {
        return problemMapper.selectTimeById(pid);
    }
    @GetMapping("/fegin/getOutput")
    public String getOutput(@RequestParam("pid") int pid) {
        return problemMapper.getOutput(pid);
    }
    @GetMapping("/fegin/getTitleAndDifficulty")
    public Map<String, String> getTitleAndDifficulty(@RequestParam("pid") int pid) {
        return problemMapper.getTitleAndDifficulty(pid);
    }

    @PostMapping("/saveRecode")
    public Result saveRecode(@RequestBody UserRecodeVO userRecodeVO) {
        problemMapper.saveRecode(userRecodeVO);
        return Result.success(null, "保存成功");
    }
}